package com.hst.capacity.application.biz.impl;

import com.hst.capacity.application.biz.FranchiseeBiz;
import com.hst.capacity.domain.common.constants.Constants;
import com.hst.capacity.domain.model.entity.franchisee.FranchiseeEntity;
import com.hst.capacity.domain.model.entity.franchisee.commision.FranchiseeCommisionEntity;
import com.hst.capacity.domain.model.entity.franchisee.customer.CustomerFranchiseeEntity;
import com.hst.capacity.domain.model.entity.franchisee.finance.FinanceFranchiseeEntity;
import com.hst.capacity.domain.model.entity.order.express.ExpressOrderEntity;
import com.hst.capacity.domain.model.entity.order.intercity.IntercityOrderEntity;
import com.hst.capacity.domain.model.entity.order.pool.OrderPoolEntity;
import com.hst.capacity.domain.model.request.franchisee.FranchiseeSaveParam;
import com.hst.capacity.domain.model.request.franchisee.commision.FranchiseeCommisionParam;
import com.hst.capacity.domain.model.request.franchisee.commision.FranchiseeCommisionSaveParam;
import com.hst.capacity.domain.model.response.franchisee.commision.FranchiseeCommisionVO;
import com.hst.capacity.domain.model.response.stat.StatVO;
import com.hst.capacity.infra.convertor.FranchiseeConvertor;
import com.hst.capacity.infra.persistence.jpa.franchisee.customer.CustomerFranchiseeRepository;
import com.hst.capacity.infra.persistence.jpa.franchisee.finance.FinanceFranchiseeRepository;
import com.hst.capacity.infra.persistence.jpa.order.express.ExOrderRepository;
import com.hst.capacity.infra.persistence.jpa.order.intercity.IcOrderRepository;
import com.hst.capacity.infra.persistence.jpa.order.pool.OrderPoolRepository;
import com.hst.capacity.infra.persistence.jpa.setting.commision.FranchiseeCommisionRepository;
import com.hst.capacity.infra.util.DateUtil;
import com.hst.capacity.infra.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class FranchiseeBizImpl implements FranchiseeBiz {

    @Autowired
    FranchiseeCommisionRepository fcRepository;

    @Autowired
    ExOrderRepository exOrderRepository;

    @Autowired
    IcOrderRepository icOrderRepository;

    @Autowired
    OrderPoolRepository orderPoolRepository;

    @Autowired
    CustomerFranchiseeRepository customerFranchiseeRepository;

    @Autowired
    FinanceFranchiseeRepository financeFranchiseeRepository;

    @Override
    public int agentCount(String idFranchiseeUser) {
        return 1;
    }

    @Override
    public List<FranchiseeCommisionVO> findFranCommisionByIdFranchisee(String idFranchisee) {
        List<FranchiseeCommisionEntity> list = fcRepository.findByIdFranchisee(idFranchisee);
        return FranchiseeConvertor.INSTANCE.covertFranCommisionLst(list);
    }

    @Override
    public List<String> findIdFranByDispacther(String idDispacther) {
        if (StringUtil.isNotBlank(idDispacther)) {
            List<String> lst = customerFranchiseeRepository.findIdFranchiseeByIdCustomer(idDispacther);
            return lst;
        }
        return null;
    }

    @Override
    public String findIdFranArrByDispacther(String idDispacther) {
        String idFranchiseeArr = null;
        if (StringUtil.isNotBlank(idDispacther)) {
            List<CustomerFranchiseeEntity> lst = customerFranchiseeRepository.findByIdCustomer(idDispacther);
            StringBuilder sb = new StringBuilder();
            if (lst != null && lst.size() > 0) {
                for (CustomerFranchiseeEntity entity : lst) {
                    sb.append("'").append(entity.getIdFranchisee()).append("'").append(",");
                }

                if (sb.toString().length() > 0) {
                    idFranchiseeArr = sb.toString();
                    int len = idFranchiseeArr.length();
                    idFranchiseeArr = idFranchiseeArr.substring(0, len - 1);
                }
            }
        }
        return idFranchiseeArr;
    }

    @Override
    public String findIdFranArrByFinance(String idFinance) {
        String idFranchiseeArr = null;
        if (StringUtil.isNotBlank(idFinance)) {
            List<FinanceFranchiseeEntity> lst = financeFranchiseeRepository.findByIdFinance(idFinance);
            StringBuilder sb = new StringBuilder();
            if (lst != null && lst.size() > 0) {
                for (FinanceFranchiseeEntity entity : lst) {
                    sb.append("'").append(entity.getIdFranchisee()).append("'").append(",");
                }

                if (sb.toString().length() > 0) {
                    idFranchiseeArr = sb.toString();
                    int len = idFranchiseeArr.length();
                    idFranchiseeArr = idFranchiseeArr.substring(0, len - 1);
                }
            }
        }
        return idFranchiseeArr;
    }

    @Override
    public FranchiseeCommisionVO findFranCommision(FranchiseeCommisionParam param) {
        return FranchiseeConvertor.INSTANCE.covertFranCommision(
                fcRepository.findByIdFranchiseeCommision(param.getIdFranchiseeCommision()));
    }

    @Override
    public String commisionSave(FranchiseeCommisionSaveParam param) {
        String channel = StringUtil.isNotBlank(param.getChannel()) ? Constants.Channel.PLATFORM : param.getChannel();
        FranchiseeCommisionEntity entity = fcRepository.findByChannelAndIdFranchiseeAndModuleType(channel, param.getIdFranchisee(),param.getModuleType());
        if (entity != null) {
            entity.setDriverRate(param.getDriverRate());
            entity.setFranchiseeRate(param.getFranchiseeRate());
        } else {
            entity = FranchiseeConvertor.INSTANCE.convert(param);
            entity.setChannel(channel);
        }
        return fcRepository.save(entity).getIdFranchiseeCommision();
    }

    @Override
    public StatVO dailyStat(String idFranchisee) {

        StatVO dailyStatVO = new StatVO();

        LocalDateTime startToday = DateUtil.getStartTodayLocalDate();
        LocalDateTime endToday = DateUtil.getEndTodayLocalDate();

        //订单总数
        int orderCount = 0;
        //流水
        float income = 0;
        //市内流水
        float innerOrderIncome = 0;
        //城际流水
        float intercityOrderIncome = 0;
        //接送机流水
        float spOrderIncome = 0;
        //完成订单数
        int finishOrderCount = 0;
        //取消订单数
        int cancelOrderCount = 0;
        //在线时长
        int onlineDuration = 0;

        List<ExpressOrderEntity> exLst = exOrderRepository.dailyStat(idFranchisee, startToday, endToday);
        if (exLst != null) {
            orderCount = orderCount + exLst.size();
            for (int i = 0; i < exLst.size(); i++) {
                ExpressOrderEntity exOrderEntity = exLst.get(i);
                if (exOrderEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_PAY_COMPLETED) {
                    innerOrderIncome = exOrderEntity.getOrderMoney();
                    income = income + innerOrderIncome;
                    finishOrderCount = finishOrderCount + 1;
                } else if (exOrderEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_CANCEL ||
                        exOrderEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_ADMIN_CANCELED ||
                        exOrderEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_DRIVER_CANCELED ||
                        exOrderEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_DISPATCHER_CANCELED) {
                    cancelOrderCount = cancelOrderCount + 1;
                }
            }
        }

        List<IntercityOrderEntity> icLst = icOrderRepository.dailyStat(idFranchisee, startToday, endToday);
        if (icLst != null) {
            orderCount = orderCount + icLst.size();
            for (int i = 0; i < icLst.size(); i++) {
                IntercityOrderEntity icOrderEntity = icLst.get(i);
                if (icOrderEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_PAY_COMPLETED) {
                    intercityOrderIncome = icOrderEntity.getOrderMoney();
                    income = income + intercityOrderIncome;
                    finishOrderCount = finishOrderCount + 1;
                } else if (icOrderEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_CANCEL ||
                        icOrderEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_ADMIN_CANCELED ||
                        icOrderEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_DRIVER_CANCELED ||
                        icOrderEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_DISPATCHER_CANCELED) {
                    cancelOrderCount = cancelOrderCount + 1;
                }
            }
        }

        List<OrderPoolEntity> spLst = orderPoolRepository.dailyStat(idFranchisee, startToday, endToday);
        if (icLst != null) {
            orderCount = orderCount + spLst.size();
            for (int i = 0; i < spLst.size(); i++) {
                OrderPoolEntity orderPoolEntity = spLst.get(i);
                if (orderPoolEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_PAY_COMPLETED) {
                    spOrderIncome = orderPoolEntity.getOrderMoney();
                    income = income + spOrderIncome;
                    finishOrderCount = finishOrderCount + 1;
                } else if (orderPoolEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_CANCEL ||
                        orderPoolEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_ADMIN_CANCELED ||
                        orderPoolEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_DRIVER_CANCELED ||
                        orderPoolEntity.getStatus() == Constants.OrderStatus.ORDER_STATUS_DISPATCHER_CANCELED) {
                    cancelOrderCount = cancelOrderCount + 1;
                }
            }
        }

        dailyStatVO.setId(idFranchisee);
        dailyStatVO.setOrderCount(orderCount);
        dailyStatVO.setIncome(income);
        dailyStatVO.setIntercityOrderIncome(intercityOrderIncome);
        dailyStatVO.setSpOrderIncome(spOrderIncome);
        dailyStatVO.setInnerOrderIncome(innerOrderIncome);
        dailyStatVO.setCancelOrderCount(cancelOrderCount);
        dailyStatVO.setFinishOrderCount(finishOrderCount);

        return dailyStatVO;
    }

}